home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK2.toast / Development Kits (Disc 2) / ScriptX / Documentation / Code Examples from Docs / compguid / threads / dispatch.sx next >
Encoding:
Text File  |  1996-05-21  |  3.0 KB  |  83 lines  |  [TEXT/ttxt]

  1. -- note that the version in the book is revised here
  2. -- one line is changed in the function dThreadFn
  3.  
  4. -- create the control function for Dispatcher.dThread
  5. function dThreadFn dispatcher -> (
  6.     repeat while true do (
  7.         if dispatcher.action == undefined then (
  8.             -- thread blocks here until the flag is acquired
  9.             acquire dispatcher.dCond -- block, don’t poll!
  10.             -- a condition activates any waiting threads and
  11.             -- is immediately closed again.
  12.             continue -- now execute the loop again
  13.         ) else (
  14.             -- work with a local copy and set action to undefined
  15.             local actionCopy := dispatcher.action
  16.             dispatcher.action := undefined
  17.             if hasKey dispatcher.dispatchList actionCopy then
  18.                 -- note that this line is different from what is in the book
  19.                 (dispatcher.dispatchList[actionCopy]) dispatcher.args
  20.             else
  21.                 format debug "undefined action" @normal
  22.         )
  23.     )
  24. )
  25.  
  26. -- this class provides a framework for a thread that waits for calls
  27. -- the thread that it creates is at high priority
  28. -- most of the time, it is blocked, waiting to be called
  29. -- when it receives a function call that it knows how to respond to,
  30. -- it calls that function with the argument it is given
  31. -- presumably, that function might activate a lower priority thread
  32. -- so that the dispatcher can go back to listening for more calls
  33. -- while the lower priority thread responds
  34.  
  35. class Dispatcher (RootObject)
  36. instance variables
  37.     dispatchList -- SortedKeyedArray
  38.     dThread -- a thread for responding to user actions
  39.     dCond -- a condition that prevents us from trying to
  40.     -- respond to a new action until the old one is dispatched
  41.     action -- name of action we are currently responding to
  42.     args -- list of arguments that goes with action
  43. instance methods
  44.     method init self #rest args -> (
  45.         self.dispatchList := new SortedKeyedArray
  46.         -- note that the condition is defined before the thread
  47.         -- the thread starts active, and immediately blocks while
  48.         -- waiting to acquire the condition
  49.         self.dCond := new Condition label:self
  50.         self.dThread := new RegularThread \
  51.             func:dThreadFn arg:self priority:@high
  52.         self.action := undefined
  53.         self.args := undefined
  54.         apply nextMethod self args
  55.     )
  56.     method pleaseDo self act argument -> (
  57.         if (hasKey self.dispatchList act) then (
  58.             self.action := act
  59.             self.args := argument
  60.             relinquish self.dCond -- open the gate
  61.         ) else (
  62.             format debug "action not defined here" @normal
  63.         )
  64.     )
  65. end -- (Dispatcher class definition)
  66.  
  67.  
  68.  
  69.  
  70. global gDispatcher := new Dispatcher -- create an instance
  71. -- the init method on Dispatcher automatically creates a thread
  72. -- define the functions that will be called
  73. global fn func1 x -> format debug "Function 1 with %*\n" x @normal
  74. global fn func2 x -> format debug "Function 2 with %*\n" x @normal
  75. global fn func3 x -> format debug "Function 3 with %*\n" x @normal
  76. -- now add key-value pairs, addMany is a method on Collection
  77. addMany gDispatcher.dispatchList #(@act1:func1, @act2:func2, @act3:func3)
  78.  
  79. -- now test the dispatcher
  80. pleaseDo gDispatcher @act1 ("Larry" as String)
  81. pleaseDo gDispatcher @act2 ("Curly" as String)
  82. pleaseDo gDispatcher @act3 ("Moe" as String)
  83.